﻿#pragma once
#include<map>
namespace LK
{
		template<>struct ptr<Reflection::TypeLibrary> :ptr<Object>
		{
			PMETHODS(ptr, Reflection::TypeLibrary);
			/**
			@brief 获取全局命名空间的引用*/
		Reflection::PNamespaceNode& GetGlobleNamespaceRef()const;
			/**
			@brief 获取分隔符的引用*/
			ptr<String> GetSeparatorRef()const;
			/**
			@brief 根据ptr<Type>来获取相关PTypeNode
			@note 如果找不到对应的PTypeNode，则返回NULL
			@warning 传入的ptr<Type>必须是PureType，否则将返回NULL*/
			Reflection::PTypeNode GetTypeNodeByInfo(const ptr<Type>&t)const;
			/**
			@brief 根据ID来获取相关PTypeNode
			@note 如果找不到对应的PTypeNode，则返回NULL*/
			Reflection::PTypeNode GetTypeNodeByInfo(index_t id)const;
			/**
			@brief 根据类型信息来设置相关PTypeNode
			@warning 传入的ptr<Type>必须是PureType，否则将抛出异常*/
			void SetTypeNodeByInfo(const ptr<Type>&t, Reflection::PTypeNode const&node)const;
		private:
			friend Reflection::LibraryNode;
			friend ptr<Reflection::LibraryNode>;
		};
	namespace Reflection
	{
		struct TypeLibrary:Object//表示一个类型库
		{
			BMETHODS(ptr<TypeLibrary>,TypeLibrary)
			/**
			@brief 全局命名空间*/
			PNamespaceNode GlobleNamespace;
			/**
			@brief 分隔符，默认是“.”
			@note 该分隔符设置将影响路径解析和输出结果*/
			ptr<String> Separator;
			/**
			@brief 默认构造函数，构造一个空的类型库*/
			TypeLibrary();
			/**
			@brief 根据类型信息来设置相关PTypeNode
			@warning 传入的ptr<Type>必须是PureType，否则将抛出异常*/
			void SetTypeNodeByInfo(const ptr<Type>&t, PTypeNode const&node);
			/**
			@brief 获取全局命名空间，并确保其非空*/
			PNamespaceNode& GetGlobleNamespaceRef();
			/**
			@brief 获取静态的类型映射（如果映射为空，则自动生成基本类型映射）*/
			ptr<Collection::IArray<PTypeNode>>& GetStaticTypesRef();
			/**
			@brief 析构函数*/
			~TypeLibrary();
		private:
			/**
			@brief 静态的类型Id到类型节点的映射
			@brief 静态类型不可以被移除*/
			ptr<Collection::IArray<PTypeNode>> StaticTypes;
			/**
			@brief 动态的类型Id到类型节点的映射
			@note 动态类型可被移除*/
			std::map<index_t, PTypeNode> DynamicTypes;
			friend LibraryNode;
			friend ptr<LibraryNode>;
			friend ptr<TypeLibrary>;
		};
	}
}
